#ifndef SYLAR_THREAD_H
#define SYLAR_THREAD_H
#include <memory>
#include <thread>
#include <unistd.h>
#include <iostream>
#include <stdint.h>
#include <pthread.h>
#include <semaphore.h>
#include <functional>
#include <atomic>
#include <mutex>       // 依赖标准库的互斥锁接口（也可适配自定义互斥锁）
#include <utility>     // 用于 std::move
#include <stdexcept>   // 用于 std::system_error
namespace sylar
{
    class Semaphore
    {
    public:
        Semaphore(uint32_t count = 0);
        ~Semaphore();
        void wait();
        void notify();

    private:
        Semaphore(const Semaphore &) = delete;
        Semaphore(const Semaphore &&) = delete;
        Semaphore &operator=(const Semaphore &) = delete;

    private:
        sem_t m_semaphore;
    };
    template <typename Mutex>
    class ScopedLockImpl
    {
    public:
        // 类型别名，方便外部访问互斥锁类型
        using mutex_type = Mutex;

        // （1）默认构造：不持有任何锁
        ScopedLockImpl() noexcept
            : m_mutex(nullptr), m_owns_lock(false) {}

        // （2）构造并锁定互斥锁
        explicit ScopedLockImpl(Mutex &mutex)
            : m_mutex(&mutex), m_owns_lock(false)
        {
            lock(); // 构造时自动锁定
        }

        // （3）构造但不锁定互斥锁（defer_lock_t 标记）
        ScopedLockImpl(Mutex &mutex, std::defer_lock_t) noexcept
            : m_mutex(&mutex), m_owns_lock(false) {}

        // （4）移动构造：转移锁的所有权
        ScopedLockImpl(ScopedLockImpl &&other) noexcept
            : m_mutex(other.m_mutex), m_owns_lock(other.m_owns_lock)
        {
            other.m_mutex = nullptr;   // 源对象不再指向互斥锁
            other.m_owns_lock = false; // 源对象不再持有锁
        }

        // （5）禁止拷贝构造和拷贝赋值（避免双重解锁）
        ScopedLockImpl(const ScopedLockImpl &) = delete;
       ScopedLockImpl &operator=(const ScopedLockImpl &) = delete;

        // （6）移动赋值：转移锁的所有权
        ScopedLockImpl &operator=(ScopedLockImpl &&other) noexcept
        {
            if (this != &other)
            {
                // 先解锁当前对象持有的锁（如果持有）
                if (m_owns_lock)
                {
                    m_mutex->unlock();
                }
                // 转移所有权
                m_mutex = other.m_mutex;
                m_owns_lock = other.m_owns_lock;
                // 源对象置空
                other.m_mutex = nullptr;
                other.m_owns_lock = false;
            }
            return *this;
        }

        // （7）析构：自动解锁（仅在持有锁时）
        ~ScopedLockImpl()
        {
            if (m_owns_lock)
            {
                m_mutex->unlock();
            }
        }

        // （8）手动锁定互斥锁
        void lock()
        {
            if (!m_mutex)
            {
                throw std::system_error(std::make_error_code(std::errc::operation_not_permitted),
                                        "ScopedLock: no mutex associated");
            }
            if (m_owns_lock)
            {
                throw std::system_error(std::make_error_code(std::errc::resource_deadlock_would_occur),
                                        "ScopedLock: already owns the lock");
            }
            m_mutex->lock(); // 调用互斥锁的锁定方法（可能抛异常）
            m_owns_lock = true;
        }

        // （9）手动解锁互斥锁
        void unlock()
        {
            if (!m_owns_lock)
            {
                throw std::system_error(std::make_error_code(std::errc::operation_not_permitted),
                                        "ScopedLock: does not own the lock");
            }
            m_owns_lock = false;
            m_mutex->unlock(); // 调用互斥锁的解锁方法
        }
        // （11）查询当前对象是否持有锁
        bool owns_lock() const noexcept
        {
            return m_owns_lock;
        }
        const Mutex *mutex() const noexcept
        {
            return m_mutex;
        }
        Mutex *mutex() noexcept
        {
            return m_mutex;
        }

    private:
        Mutex *m_mutex;   // 指向关联的互斥锁（用指针支持移动和默认构造）
        std::atomic<bool> m_owns_lock; // 标记当前对象是否持有锁
    };
    template <class T>
    class ReadScopedLockImpl
    {
    public:
        ReadScopedLockImpl(T &mutex) : m_mutex(mutex)
        {
            m_mutex.rdlock();
            m_locked = true;
        }
        ~ReadScopedLockImpl()
        {
            if (m_locked)
                unlock();
        }
        void lock()
        {
            if (!m_locked)
            {
                m_mutex.rdlock();
                m_locked = true;
            }
        }
        void unlock()
        {
            if (m_locked)
            {
                m_locked = false;
                m_mutex.unlock();
            }
        }

    private:
        T &m_mutex;
        bool m_locked;
    };

    template <class T>
    class WriteScopedLockImpl
    {
    public:
        WriteScopedLockImpl(T &mutex) : m_mutex(mutex)
        {
            m_mutex.wrlock();
            m_locked = true;
        }
        ~WriteScopedLockImpl()
        {
            if (m_locked)
                unlock();
        }
        void lock()
        {
            if (!m_locked)
            {
                m_mutex.wrlock();
                m_locked = true;
            }
        }
        void unlock()
        {
            if (m_locked)
            {
                m_locked = false;
                m_mutex.unlock();
            }
        }

    private:
        T &m_mutex;
        bool m_locked;
    };
    class Mutex
    {
    public:
        // 定义ScopedLockImpl与当前Mutex的绑定类型，方便外部使用
        typedef ScopedLockImpl<Mutex> Lock;

        // 构造函数：初始化互斥锁（默认属性）
        Mutex()
        {
            // 初始化互斥锁，使用默认属性（非递归、共享模式等由系统默认）
            int ret = pthread_mutex_init(&m_mutex, nullptr);
            if (ret != 0)
            {
                // 实际框架中可能用日志输出错误，这里简化处理
                std::cerr << "pthread_mutex_init failed, error=" << ret << std::endl;
                // 初始化失败可考虑抛异常或终止，根据框架 error handling 策略
                abort();
            }
        }

        // 析构函数：销毁互斥锁
        ~Mutex()
        {

            int ret = pthread_mutex_destroy(&m_mutex);
            if (ret != 0)
            {
                std::cerr << "pthread_mutex_destroy failed, error=" << ret << std::endl;
            }
        }

        // 加锁（阻塞式，直到获取锁）
        void lock()
        {
            int ret = pthread_mutex_lock(&m_mutex);
            if (ret != 0)
            {
                std::cerr << "pthread_mutex_lock failed, error=" << ret << std::endl;
                abort();
            }
        }

        // 解锁
        void unlock()
        {
            int ret = pthread_mutex_unlock(&m_mutex);
            if (ret != 0)
            {
                std::cerr << "pthread_mutex_unlock failed, error=" << ret << std::endl;
                abort();
            }
        }

        // 尝试加锁（非阻塞，立即返回）
        // 可选实现，供需要非阻塞场景使用
        bool trylock()
        {
            int ret = pthread_mutex_trylock(&m_mutex);
            if (ret == 0)
            {
                return true; // 成功获取锁
            }
            else if (ret == EBUSY)
            {
                return false; // 锁已被持有
            }
            else
            {
                std::cerr << "pthread_mutex_trylock failed, error=" << ret << std::endl;
                abort();
            }
        }

    private:
        // 禁用拷贝和移动，避免锁资源被意外复制
        Mutex(const Mutex &) = delete;
        Mutex(Mutex &&) = delete;
        Mutex &operator=(const Mutex &) = delete;
        Mutex &operator=(Mutex &&) = delete;

    private:
        pthread_mutex_t m_mutex; // 底层POSIX互斥锁
    };
    class NULLMutex
    {
    public:
        typedef ScopedLockImpl<NULLMutex> Lock;
        NULLMutex() {}
        ~NULLMutex() {}
        void lock() {}
        void unlock() {}
        void trylock() {}

    private:
    };
    class RWMutex
    {
    public:
        typedef ReadScopedLockImpl<RWMutex> ReadLock;
        typedef WriteScopedLockImpl<RWMutex> WriteLock;
        RWMutex()
        {
            pthread_rwlock_init(&m_lock, nullptr);
        }
        ~RWMutex()
        {
            pthread_rwlock_destroy(&m_lock);
        }
        void rdlock()
        {
            pthread_rwlock_rdlock(&m_lock);
        }
        void wrlock()
        {
            pthread_rwlock_wrlock(&m_lock);
        }
        void unlock()
        {
            pthread_rwlock_unlock(&m_lock);
        }

    private:
        pthread_rwlock_t m_lock;
    };
    class Thread
    {
    public:
        typedef std::shared_ptr<Thread> ptr;
        Thread(std::function<void()> cb, const std::string &name);
        ~Thread();
        pid_t getId() const { return m_id; }
        void join();
        static Thread *GetThis();
        static void SetName(const std::string &name);
        static const std::string &getName();
        static const std::string &GetName();
        std::function<void()> m_cb;

    private:
        Thread(const Thread &) = delete;
        Thread(const Thread &&) = delete;
        Thread &operator=(const Thread &other) = delete;
        Thread &operator=(const Thread &&other) = delete;
        static void *run(void *arg);

    private:
        std::string m_name;

        pid_t m_id = -1;
        pthread_t m_thread = 0;
        Semaphore m_semaphore;
    };
    class Spinlock
    {
    public:
        typedef ScopedLockImpl<Spinlock> Lock;

        Spinlock()
        {
            pthread_spin_init(&m_mutex, 0);
        }
        ~Spinlock()
        {
            pthread_spin_destroy(&m_mutex);
        }
        void lock()
        {
            pthread_spin_lock(&m_mutex);
        }
        void unlock()
        {
            pthread_spin_unlock(&m_mutex);
        }

    private:
        pthread_spinlock_t m_mutex;
    };
    class CSALock
    {
    public:
        typedef ScopedLockImpl<CSALock> Lock;
        CSALock()
        {
        }
        ~CSALock()
        {
        }
        void lock()
        {
            while (std::atomic_flag_test_and_set_explicit(&m_mutex, std::memory_order_acquire))
                ;
        }
        void unlock()
        {
            std::atomic_flag_clear_explicit(&m_mutex, std::memory_order_release);
        }

    private:
        volatile std::atomic_flag m_mutex;
    };
}

#endif
